package com.tencent.wxcloudrun.manager;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tencent.wxcloudrun.domain.TStoreCard;
import com.tencent.wxcloudrun.domain.TUserCardApply;
import com.tencent.wxcloudrun.domain.TUserCardApplyImg;
import com.tencent.wxcloudrun.domain.TUserCardRecord;
import com.tencent.wxcloudrun.dto.UserCardExportRecordResDTO;
import com.tencent.wxcloudrun.dto.UserCardListRecordResDTO;
import com.tencent.wxcloudrun.exception.BusinessException;
import com.tencent.wxcloudrun.service.*;
import com.tencent.wxcloudrun.util.DateUtils;
import com.tencent.wxcloudrun.vo.request.card.*;
import com.tencent.wxcloudrun.vo.request.wx.WxUploadfileRequest;
import com.tencent.wxcloudrun.vo.response.card.*;
import com.tencent.wxcloudrun.vo.response.wx.WxUploadfileResponse;

import lombok.extern.slf4j.Slf4j;

/**
 * @Author ZhaoZiYin
 * @Date 2025/4/22
 * @Description 订单管理端
 */
@Service
@Slf4j
public class UserCardManager {

    @Resource
    private WxManager wxManager;

    @Resource
    private TStoreCardService storeCardService;

    @Resource
    private TUserCardService userCardService;

    @Resource
    private TUserCardApplyService userCardApplyService;

    @Resource
    private TUserCardApplyImgService userCardApplyImgService;

    @Resource
    private TUserCardRecordService userCardRecordService;

    /**
     * @Author: ZhaoZiYin
     * @Date: 2025/5/13
     * @Params: [reqVo]
     * @Return: UserCardApplyResVo
     * @Description: 申请卡片
     */
    @Transactional(rollbackFor = Exception.class)
    public UserCardApplyResVo apply(UserCardApplyReqVo reqVo) {
        // 保存申请卡片
        TUserCardApply apply = reqVo.build();
        userCardApplyService.save(apply);

        // 保存申请卡片图片列表
        List<TUserCardApplyImg> applyImgList = reqVo.buildImg(apply.getId());
        if (!CollectionUtils.isEmpty(applyImgList)) {
            userCardApplyImgService.saveBatch(applyImgList);
        }
        return null;
    }

    /**
     * @Author: ZhaoZiYin
     * @Date: 2025/5/13
     * @Params: [reqVo]
     * @Return: UserCardCancelApplyResVo
     * @Description: 取消申请卡片
     */
    @Transactional(rollbackFor = Exception.class)
    public UserCardCancelApplyResVo cancelApply(UserCardCancelApplyReqVo reqVo) {
        userCardApplyService.cancelApply(reqVo.getUserCardApplyId());
        return null;
    }

    /**
     * @Author: ZhaoZiYin
     * @Date: 2025/5/13
     * @Params: [reqVo]
     * @Return: UserCardQueryApplyResVo
     * @Description: 查询申请记录
     */
    public UserCardQueryApplyResVo queryApply(UserCardQueryApplyReqVo reqVo) {
        UserCardQueryApplyResVo resVo = new UserCardQueryApplyResVo();
        TUserCardApply apply = userCardApplyService.getById(reqVo.getUserCardApplyId());
        TStoreCard card = new TStoreCard();
        if (Objects.nonNull(apply)) {
            card = storeCardService.getById(apply.getCardId());
        }
        List<TUserCardApplyImg> applyImgList = userCardApplyImgService.getByCardApplyId(reqVo.getUserCardApplyId());
        resVo.build(apply, card, applyImgList);
        return resVo;
    }

    /**
     * @Author: ZhaoZiYin
     * @Date: 2025/5/13
     * @Params: [reqVo]
     * @Return: UserCardListApplyResVo
     * @Description: 查询申请列表
     */
    public IPage<UserCardListApplyResVo> listApply(UserCardListApplyReqVo reqVo) {
        IPage<UserCardListApplyResVo> resPage = new Page<>(reqVo.getCurrent(), reqVo.getSize());
        List<UserCardListApplyResVo> resVoList = new ArrayList<>();
        Page<TUserCardApply> page = new Page<>(reqVo.getCurrent(), reqVo.getSize());
        Page<TUserCardApply> applyPage = userCardApplyService.listApply(page, reqVo.getQryUserId(), reqVo.getStatus());
        if (!CollectionUtils.isEmpty(applyPage.getRecords())) {
            List<Long> cardIdList =
                applyPage.getRecords().stream().map(TUserCardApply::getCardId).collect(Collectors.toList());
            List<TStoreCard> cardList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(cardIdList)) {
                cardList = storeCardService.listByIds(cardIdList);
            }
            for (TUserCardApply apply : applyPage.getRecords()) {
                UserCardListApplyResVo resVo = new UserCardListApplyResVo();
                resVo.build(apply, cardList);
                resVoList.add(resVo);
            }
        }
        resPage.setTotal(applyPage.getTotal());
        resPage.setRecords(resVoList);
        return resPage;
    }

    /**
     * @Author: ZhaoZiYin
     * @Date: 2025/4/22
     * @Params: [reqVo]
     * @Return: UserCardListResVo
     * @Description: 查询用户卡片
     */
    public UserCardListResVo listCard(UserCardListReqVo reqVo) {
        UserCardListResVo resVo = new UserCardListResVo();
        resVo.setCardList(userCardService.listCard(reqVo.getUserId()));
        return resVo;
    }

    /**
     * @Author: ZhaoZiYin
     * @Date: 2025/4/22
     * @Params: [reqVo]
     * @Return: UserCardQueryRecordResVo
     * @Description: 查询用户卡片记录
     */
    public UserCardListRecordResVo listRecord(UserCardListRecordReqVo reqVo) {
        UserCardListRecordResVo resVo = new UserCardListRecordResVo();
        List<TUserCardRecord> recordList =
            userCardRecordService.queryCardRecord(reqVo.getQryUserId(), reqVo.getCardId());
        if (!CollectionUtils.isEmpty(recordList)) {
            List<UserCardListRecordResDTO> recordResList = new ArrayList<>();
            for (TUserCardRecord record : recordList) {
                UserCardListRecordResDTO resDTO = new UserCardListRecordResDTO();
                resDTO.setUserRecordId(record.getId());
                resDTO.setType(record.getType());
                resDTO.setCount(record.getCount());
                resDTO.setMemo(record.getMemo());
                resDTO.setCreatedTime(record.getCreatedTime().format(DateUtils.LOCAL_DATE_TIME_FORMATTER));
                recordResList.add(resDTO);
            }
            resVo.setRecordList(recordResList);
        }
        return resVo;
    }

    /**
     * @Author: ZhaoZiYin
     * @Date: 2025/6/3
     * @Params: [reqVo]
     * @Return: UserCardUseResVo
     * @Description: 使用卡片
     */
    public UserCardUseResVo use(UserCardUseReqVo reqVo) {
        UserCardUseResVo resVo = new UserCardUseResVo();
        userCardService.use(reqVo);
        TUserCardRecord record = reqVo.build();
        userCardRecordService.save(record);
        return resVo;
    }

    /**
     * @Author: ZhaoZiYin
     * @Date: 2025/6/3
     * @Params: [reqVo]
     * @Return: UserCardExportRecordResVo
     * @Description: 导出使用卡片记录
     */
    public UserCardExportRecordResVo exportUseRecord(UserCardExportUseRecordReqVo reqVo) {
        UserCardExportRecordResVo resVo = new UserCardExportRecordResVo();
        // 查询数据
        List<UserCardExportRecordResDTO> resDTOList = userCardRecordService.listUseRecord(reqVo.getActiId());
        if (CollectionUtils.isEmpty(resDTOList)) {
            return resVo;
        }

        // 生成Excel
        String sysPath = System.getProperty("user.dir");
        String currTime = String.valueOf(System.currentTimeMillis());
        String filePath = "card_use_record" + File.separator + reqVo.getActiId() + File.separator + "acti_card_record" + currTime + ".xlsx";
        String fileName = sysPath + File.separator + filePath;
        File file = new File(fileName);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        EasyExcel.write(fileName, UserCardExportRecordResDTO.class).sheet("使用记录").doWrite(resDTOList);

        // 上传文件
        WxUploadfileRequest wxReq = new WxUploadfileRequest();
        wxReq.setPath(filePath);
        WxUploadfileResponse wxRes = wxManager.wxUploadfile(wxReq, file);
        if (wxRes.getErrcode() != 0) {
            throw new BusinessException(wxRes.getErrmsg());
        }

        resVo.setFileId(wxRes.getFileId());
        return resVo;
    }

}
